package com.cbgolf.oa.util;


import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Build;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.RequiresApi;
import android.support.v4.content.FileProvider;
import android.support.v4.util.ArrayMap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.alibaba.fastjson.JSONObject;
import com.cbgolf.oa.R;
import com.cbgolf.oa.app.App;
import com.cbgolf.oa.app.AppManager;
import com.cbgolf.oa.manager.DialogManager;
import com.cbgolf.oa.manager.DialogManager.IDialogManagerWaiter;
import com.cbgolf.oa.net.NetCallBack;
import com.cbgolf.oa.net.NetUtils;
import com.cbgolf.oa.net.Web;
import com.cbgolf.oa.net.WebAPI;
import com.cbgolf.oa.widget.autolayout.utils.AutoUtil;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class UpdateManager {

  /* 下载中 */
  private static final int DOWNLOAD = 1;
  /* 下载结束 */
  private static final int DOWNLOAD_FINISH = 2;
  private static final int DOWNLOAD_ERROR = 3;

  /* 记录进度条数量 */
  private int progress;
  private Context mContext;
  private String downloadUrl = "";
  private int type;
  private boolean isMandatoryUpdate = false;
  private IVersionWorker worker;

  private File apkFile;
  private boolean isDowning = false;

  private TextView titleTv;
  private TextView msgTv;
  private TextView progressTv;
  private ProgressBar progressBar;
  private Dialog Downdialog;
  private Dialog updataDialog;

  public interface IVersionWorker {

    void requestUpdatePermission();

    void toSettingGetInstallPermission();
  }

  Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
      switch (msg.what) {
        // 正在下载
        case DOWNLOAD:
          // 设置进度条位置
          progressBar.setProgress(progress);
          progressTv.setText(progress + "%");
          break;
        case DOWNLOAD_FINISH:
          titleTv.setText("下载完成");
          msgTv.setText("已完成");
          if (null != Downdialog) {
            Downdialog.dismiss();
          }
          isDowning = false;
          installApk();
          break;
        case DOWNLOAD_ERROR:
          Util.show("服务器维护中，无法下载");
          titleTv.setText("下载失败");
          Downdialog.setCancelable(!isMandatoryUpdate);
          isDowning = false;
          break;
        default:
          break;
      }
    }
  };

  public UpdateManager(Context context, IVersionWorker worker, int type) {
    this.type = type;
    this.mContext = context;
    this.worker = worker;
  }


  /**
   * 检测软件更新
   */
  public void checkUpdate() {
    Map<String, String> map = new ArrayMap<>();
    map.put("type", DataUtil.VERSION_TYPE);
    showProgress();
    Web.getOK(WebAPI.version_get, map, new NetCallBack(response -> {
      stopProgress();
      if (NetUtils.SUCCESS != response.statusCode) {
        checkUpdateFail(response.errorMsg);
        return;
      }
      checkUpdateSuccess(DataUtil.getJson(response.result));

    }));
  }

  private void checkUpdateSuccess(JSONObject json) {
    String versionNum = DataUtil.getJsonString(json, "versionNumber");
    downloadUrl = DataUtil.getJsonString(json, "downloadAddress");
    String instructions = DataUtil.getJsonString(json, "instructions");
    String title = DataUtil.getJsonString(json, "title");
    isMandatoryUpdate = DataUtil.getJsonBoolean(json, "isMandatoryUpdate");
    PackageManager pm = App.getContext().getPackageManager();
    int versionCode = 0;
    try {
      PackageInfo packageInfo = pm.getPackageInfo(App.getContext().getPackageName(), 0);
      versionCode = packageInfo.versionCode;
    } catch (NameNotFoundException e) {
      e.printStackTrace();
    }
    if (Util.isNull(versionNum)) {
      return;
    }
    int num = TypeUtil.getInt(versionNum);
    if (versionCode < num) {
      showUpdateDialog(title, instructions);
      return;
    }
    if (versionCode >= num && versionCode != 0 && type == 1) {
      showNewestDialog();
    }
  }

  private void showProgress() {
    if (type == 1) {
      AnimaUtil.showLoading(AppManager.getNewInstance().currentActivity());
    }
  }

  private void stopProgress() {
    AnimaUtil.stopLoading();
  }

  private void checkUpdateFail(String errorMsg) {
    if (type == 1) {
      Util.show(errorMsg);
    }
  }

  private void showNewestDialog() {
    final Dialog dialog = new Dialog(mContext, R.style.mDialog);
    View view = LayoutInflater.from(mContext).inflate(R.layout.dialog_version_newest, null);
    View layout = view.findViewById(R.id.dialog_version_newest_layout_ll);
    LinearLayout.LayoutParams ll = (LinearLayout.LayoutParams) layout.getLayoutParams();
    ll.width = ScreenUtil.getWidth() - DensityUtil.dip2px(mContext, 58);
    ll.height = LayoutParams.WRAP_CONTENT;
    layout.setLayoutParams(ll);
    TextView sureTv = (TextView) view.findViewById(R.id.dialog_version_newest_sure_tv);
    AutoUtil.auto(view);
    dialog.setContentView(view);
    sureTv.setOnClickListener(v -> {
      dialog.cancel();
      dialog.dismiss();
    });
    dialog.show();
  }


  /**
   * 获取软件版本号
   */
  private int getVersionCode(Context context) {
    int versionCode = 0;
    try {
      // 获取软件版本号，对应AndroidManifest.xml下android:versionCode
      versionCode = context.getPackageManager()
          .getPackageInfo(context.getPackageName(), 0).versionCode;
    } catch (NameNotFoundException e) {
      e.printStackTrace();
    }
    return versionCode;
  }


  /**
   * 显示软件更新对话框
   */
  private void showUpdateDialog(String title, String content) {
    if (null != updataDialog && updataDialog.isShowing()) {
      return;
    }
    if (null != Downdialog && Downdialog.isShowing()) {
      return;
    }
    if (!isMandatoryUpdate) {
      if (App.isUpDataCheckPermission || App.isUpDataCanceled || App.isUpdataShowDownLoad) {
        return;
      }
    }
    updataDialog = new Dialog(mContext, R.style.mDialog);
    View view = LayoutInflater.from(mContext).inflate(R.layout.dialog_version, null);
    LinearLayout layout = view.findViewById(R.id.dialog_version_layout_ll);
    TextView titleTv = view.findViewById(R.id.dialog_version_title_tv);
    TextView contentTv = view.findViewById(R.id.dialog_version_content_tv);
    TextView cancelTv = view.findViewById(R.id.dialog_version_cancel_tv);
    TextView sureTv = view.findViewById(R.id.dialog_version_sure_tv);
    View line = view.findViewById(R.id.dialog_version_line);
    AutoUtil.auto(view);
    updataDialog.setContentView(view);
    ViewUtils.setLlLayoutParams(layout,
        (int) (ScreenUtil.getWidth() - mContext.getResources().getDimension(R.dimen.px115)),
        LayoutParams.WRAP_CONTENT);
    titleTv.setText("发现新版本");
    if (Util.isNull(content)) {
      content = "全新改版，全新用户体验，增加更多有趣功能\n" +
          "还不快去更新！";
    }
    contentTv.setText(content);
    if (isMandatoryUpdate) {
      cancelTv.setVisibility(View.GONE);
      line.setVisibility(View.GONE);
    }
    updataDialog.setCancelable(false);
    sureTv.setOnClickListener(v -> {
      updataDialog.cancel();
      updataDialog.dismiss();
      if (!PermissionUtils.hasAllCameraPermission() && null != worker) {
        App.isUpDataCheckPermission = true;
        worker.requestUpdatePermission();
      } else {
        showDownloadDialog();
      }
    });
    cancelTv.setOnClickListener(v -> {
      updataDialog.cancel();
      updataDialog.dismiss();
      App.isUpDataCanceled = true;
    });
    updataDialog.show();
  }

  /**
   * 显示软件下载对话框
   */

  public void showDownloadDialog() {
    App.isUpdataShowDownLoad = true;
    if (Util.isNull(downloadUrl)) {
      Util.show("下载服务器维护中，暂无法下载");
      return;
    }
    Downdialog = new Dialog(mContext, R.style.mDialog);
    Downdialog.setContentView(R.layout.dialog_down_progress);
    View layout = Downdialog.findViewById(R.id.dialog_down_layout_ll);
    titleTv = (TextView) Downdialog.findViewById(R.id.dialog_down_title_tv);
    msgTv = (TextView) Downdialog.findViewById(R.id.dialog_down_msg_tv);
    progressBar = (ProgressBar) Downdialog.findViewById(R.id.dialog_down_progressbar);
    progressTv = (TextView) Downdialog.findViewById(R.id.dialog_down_pros_tv);
    LinearLayout.LayoutParams ll = (LinearLayout.LayoutParams) layout.getLayoutParams();
    ll.width =
        (int) (ScreenUtil.getWidth() - mContext.getResources().getDimension(R.dimen.px116));
    ll.height = LayoutParams.WRAP_CONTENT;
    layout.setLayoutParams(ll);
    Downdialog.setCancelable(!isMandatoryUpdate);
    Downdialog.show();
    downLoadApk();
  }

  private void downLoadApk() {
    if (isDowning) {
      return;
    }
    ThreadFactory mThreadFactory = r -> new Thread(r);
    ExecutorService singleThreadPool = new ThreadPoolExecutor(1, 1,
        0L, TimeUnit.MILLISECONDS,
        new LinkedBlockingQueue<>(1024), mThreadFactory, new ThreadPoolExecutor.AbortPolicy());
    singleThreadPool.execute(() -> doDownLoad());
    singleThreadPool.shutdown();

//    new Thread(() -> {
//
//    }).start();
  }

  private void doDownLoad() {
    try {
      isDowning = true;
      URL url = new URL(downloadUrl);
      // 创建连接
      HttpURLConnection conn = (HttpURLConnection) url.openConnection();
      conn.connect();
      // 获取文件大小
      int length = conn.getContentLength();
      // 创建输入流
      InputStream in = conn.getInputStream();
      // 创建文件
      File path =
          FileUtils.getDiskCacheDir(App.getContext(), "apk");
      try {
        if (!path.exists()) {
          path.mkdirs();
        }
        apkFile = new File(path, "cbgolf.apk");
        if (apkFile.exists()) {
          apkFile.delete();
        }
      } catch (Exception e) {
      }
      FileOutputStream fos = new FileOutputStream(apkFile);
      int count = 0;
      // 缓存
      byte buf[] = new byte[1024 * 10];
      int len = 0;
      // 写入到文件中
      while ((len = in.read(buf)) != -1) {
        count += len;
        // 计算进度条位置
        if (0 != count && 0 != length) {
          progress = (int) (((float) count / length) * 100);
        }
        // 更新进度
        handler.sendEmptyMessage(DOWNLOAD);
        // 写入文件
        fos.write(buf, 0, len);
        if (count == length || len <= 0 || progress == 100) {
          // 下载完成
          handler.sendEmptyMessage(DOWNLOAD_FINISH);
        }

      }
      fos.close();
      in.close();
    } catch (Exception e) {
      e.printStackTrace();
      handler.sendEmptyMessage(DOWNLOAD_ERROR);
    }
  }

  /**
   * 安装APK文件
   */
  public void installApk() {
    if (!apkFile.exists()) {
      Util.show("安装包已损换，无法安装");
      return;
    }
    boolean haveInstallPermission;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      //先获取是否有安装未知来源应用的权限
      haveInstallPermission = mContext.getPackageManager().canRequestPackageInstalls();
      if (!haveInstallPermission) {
        DialogManager.getInstance().showSettingDialog(mContext,
            "安装应用需要打开未知来源权限，请去设置中开启权限",true,
            new IDialogManagerWaiter() {
              @Override
              public void doSubmit() {
                if (VERSION.SDK_INT >= VERSION_CODES.O) {
                  startInstallPermissionSettingActivity();
                }
              }

              @Override
              public void doCancel() {
              }
            });
        return;
      }
    }
    try {
      // 通过Intent安装APK文件
      Intent intent = getFileIntent(apkFile);
      mContext.startActivity(intent);
    } catch (Exception e) {

    }
  }

  @RequiresApi(api = Build.VERSION_CODES.O)
  private void startInstallPermissionSettingActivity() {
    if (null != worker) {
      worker.toSettingGetInstallPermission();
    }
  }


  public Intent getFileIntent(File file) {
    Uri uri = getUriForFile(file);
    String type = getMIMEType(file);
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.addCategory(Intent.CATEGORY_DEFAULT);
    //判读版本是否在7.0以上
    if (Build.VERSION.SDK_INT >= VERSION_CODES.N) {
      //添加这一句表示对目标应用临时授权该Uri所代表的文件
      intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setDataAndType(uri, type);
    return intent;
  }

  public Uri getUriForFile(File file) {
    if (mContext == null || file == null) {
      Util.showNetError();
      return null;
    }
    Uri uri;
    if (Build.VERSION.SDK_INT >= 24) {
      uri = FileProvider.getUriForFile(mContext.getApplicationContext(),
          mContext.getApplicationContext().getPackageName() + ".fileprovider",
          file);
    } else {
      uri = Uri.fromFile(file);
    }
    return uri;
  }

  public static String getMIMEType(File f) {
    String type = "";
    String fName = f.getName();
    // 取得扩展名
    String end = fName
        .substring(fName.lastIndexOf(".") + 1, fName.length());
    if (Util.isEquals(end, "apk")) {
      type = "application/vnd.android.package-archive";
    } else {
      // /*如果无法直接打开，就跳出软件列表给用户选择 */
      type = "*/*";
    }
    return type;
  }
}
